package com.mxpio.erp.purchase.controller;


import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.mxpio.erp.common.enums.AuditEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.jpa.model.Order;
import com.mxpio.erp.common.order.service.OrderService;
import com.mxpio.erp.common.purchase.entity.BuyRequestOrder;
import com.mxpio.erp.common.purchase.entity.BuyRequestOrderLine;
import com.mxpio.erp.common.purchase.service.BuyRequestOrderLineService;
import com.mxpio.erp.common.purchase.service.BuyRequestOrderService;
import com.mxpio.erp.common.purchase.vo.AuditOpinionVO;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.policy.CrudContext;
import com.mxpioframework.jpa.policy.impl.SmartCrudPolicyAdapter;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import com.mxpioframework.security.util.SecurityUtils;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

@Tag(name = "BuyRequestOrderController", description = "采购申请单数据接口")
@RestController
@RequestMapping("/erp/purc/br/")
public class BuyRequestOrderController {

    @Autowired
    private BuyRequestOrderService buyRequestOrderService;

    @Autowired
    private BuyRequestOrderLineService buyRequestOrderLineService;

    @Autowired
    private OrderService orderService;

    @GetMapping("list")
    @Operation(summary = "采购申请单列表", description = "获取采购申请单列表（无分页）", method = "GET")
    public Result<List<BuyRequestOrder>> list(@Parameter(description = "查询参数") Criteria criteria) throws UnsupportedEncodingException {
        List<BuyRequestOrder> buyRequestOrder = buyRequestOrderService.list(BuyRequestOrder.class, criteria);
        return Result.OK(buyRequestOrder);
    }

    @GetMapping("page")
    @Operation(summary = "采购申请单列表", description = "获取采购申请单列表（分页）", method = "GET")
    public Result<Page<BuyRequestOrder>> page(@Parameter(description = "查询参数") Criteria criteria, @Parameter(description = "每页条数") Integer pageSize, @Parameter(description = "页号") Integer pageNo) throws UnsupportedEncodingException {
        Pageable page = PageRequest.of(pageNo - 1, pageSize);
        Page<BuyRequestOrder> buyRequestOrder = buyRequestOrderService.listPage(BuyRequestOrder.class, page, criteria);
        return Result.OK(buyRequestOrder);
    }

    @GetMapping("list/{bizNo}")
    @Operation(summary = "根据bizNo获取采购申请单", description = "根据bizNo获取采购申请单", method = "GET")
    public Result<BuyRequestOrder> getById(@Parameter(description = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        BuyRequestOrder buyRequestOrder = buyRequestOrderService.getById(BuyRequestOrder.class, bizNo);
        return Result.OK(buyRequestOrder);
    }

    @RequestMapping("save")
    @Operation(summary = "保存采购申请单", description = "保存采购申请单")
    public Result<BuyRequestOrder> save(@RequestBody BuyRequestOrder buyRequestOrder) {
        buyRequestOrderService.setPnInfo(buyRequestOrder);//关联明细信息中的默认供应商
        buyRequestOrderService.save(buyRequestOrder, new SmartCrudPolicyAdapter() {
            @Override
            public boolean beforeInsert(CrudContext context) {
                Object o = context.getEntity();
                if (o instanceof BuyRequestOrderLine) {
                    BuyRequestOrder order = context.getParent();
                    ((BuyRequestOrderLine) o).setBizNo(order.getBizNo());
                    ((BuyRequestOrderLine) o).setLineStatus(OrderStatusEnums.BuyRequestLineStatus.CREATE.getStatusCode());
                }
                return true;
            }
        });
        return Result.OK(buyRequestOrder);
    }

    @DeleteMapping("remove/{bizNos}")
    @Operation(summary = "根据bizNo删除采购申请单", description = "删除采购申请单", method = "DELETE")
    @Transactional(readOnly = false)
    public Result<BuyRequestOrder> remove(@Parameter(description = "业务单号，多个单号用英文逗号分隔") @PathVariable(name = "bizNos", required = true) String bizNos) {
        String[] bizNo = bizNos.split(",");
        for (String key : bizNo) {
            Criteria c = Criteria.create().addCriterion("bizNo", Operator.EQ, key);
            buyRequestOrderLineService.removeBatch(BuyRequestOrderLine.class, c);
            buyRequestOrderService.delete(BuyRequestOrder.class, key);
        }
        return Result.OK();
    }

    @PutMapping("audit/{bizNo}")
    @Operation(summary = "审核采购申请单", description = "审核采购申请单", method = "PUT")
    public Result<? extends Order> audit(@RequestBody AuditOpinionVO vo) {
        BuyRequestOrder order = buyRequestOrderService.getById(BuyRequestOrder.class, vo.getBizNo());
        if(AuditEnums.Purc.OK.getTypeCode().equals(vo.getAuditOpinion())){
            order.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode());
            order.setReviewer(SecurityUtils.getLoginUsername());
            order.setReviewTime(new Date());
            buyRequestOrderService.update(order);
            return Result.OK();
        }
        else if(AuditEnums.Purc.REFUSE.getTypeCode().equals(vo.getAuditOpinion())){
            order.setBpmnStatus(OrderStatusEnums.BpmnStatus.CLOSED.getStatusCode());
            order.setReviewer(SecurityUtils.getLoginUsername());
            order.setReviewTime(new Date());
            buyRequestOrderService.update(order);
            return Result.OK();
        }
        else if(AuditEnums.Purc.REJECT.getTypeCode().equals(vo.getAuditOpinion())){
            order.setBpmnStatus(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode());
            order.setReviewer(SecurityUtils.getLoginUsername());
            order.setReviewTime(new Date());
            buyRequestOrderService.update(order);
            return Result.OK();
        }
        return Result.error("非法的审核结论");
    }

    @PutMapping("submit/{bizNo}")
    @Operation(summary = "提交采购申请单", description = "提交采购申请单", method = "PUT")
    public Result<? extends Order> submit(@Parameter(description="业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        BuyRequestOrder order = buyRequestOrderService.getById(BuyRequestOrder.class,bizNo);
        if(order.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode())){
            return orderService.updateBpmnStatus(order, OrderStatusEnums.BpmnStatus.AUDITING);
        }else {
            return Result.error("非开立状态不可提交");
        }
    }

    /*@PutMapping("abandon/{bizNo}")
    @Operation(summary = "弃审采购申请单", description = "弃审采购申请单", method = "PUT")
    public Result<? extends Order> abandon(@Parameter(description="业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        BuyRequestOrder order = buyRequestOrderService.getById(BuyRequestOrder.class,bizNo);
        if(order.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode())||order.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())){
            return orderService.updateBpmnStatus(order, OrderStatusEnums.BpmnStatus.CREATE);
        }else{
            return Result.error("非审核中、已审核状态不可审核");
        }
    }*/


    /*@PutMapping("open/{bizNo}")
    @Operation(summary = "打开采购申请单", description = "打开采购申请单", method = "PUT")
    public Result<? extends Order> open(@Parameter(description = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        BuyRequestOrder order = buyRequestOrderService.getById(BuyRequestOrder.class, bizNo);
        return orderService.updateCloseStatus(order, OrderStatusEnums.CloseStatus.OPEN);
    }

    @PutMapping("close/{bizNo}")
    @Operation(summary = "关闭采购申请单", description = "关闭采购申请单", method = "PUT")
    public Result<? extends Order> close(@Parameter(description = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        BuyRequestOrder order = buyRequestOrderService.getById(BuyRequestOrder.class, bizNo);
        return orderService.updateCloseStatus(order, OrderStatusEnums.CloseStatus.CLOSED);
    }*/
}

